<template>
  <div class="app-container">
    <div class="filter-container">
      <el-form :inline="true" ref="listQuery" :model="listQuery" class="demo-form-inline">
        <el-form-item prop="attachmentType" label="附件类型">
          <el-radio-group v-model="listQuery.attachmentType">
            <el-radio-button label="" key="">全部</el-radio-button>
            <el-radio-button v-for="(item,index) in getEnumList('AttachmentType')" :label="item.key" :key="index">{{item.value}}</el-radio-button>
          </el-radio-group>
        </el-form-item>
        <el-form-item prop="fileType" label="文件类型">
          <el-select v-model="listQuery.fileType" class="m-2" placeholder="请选择">
            <el-option key="" label="全部" value="" />
            <el-option v-for="item in getDictList('FileType')" :key="item.key" :label="`${item.key} - ${item.value}`" :value="item.key" />
          </el-select>
        </el-form-item>
        <el-form-item prop="fileName" label="名称">
          <el-input v-model="listQuery.fileName" placeholder="名称(关键词)" @keyup.enter="handleFilter" />
        </el-form-item>
        <!--
        <el-form-item prop="module" label="适用模块">
          <el-select v-model="listQuery.module" class="m-2" placeholder="请选择">
            <el-option key="" label="全部" value="" />
            <el-option v-for="item in getEnumList('Module')" :key="item.key" :label="item.value" :value="item.key" />
          </el-select>
        </el-form-item>
        -->
        <el-form-item>
          <el-button v-waves type="success" icon="Search" @click="handleFilter">
            查询
          </el-button>
          <el-button icon="Refresh" @click="handleResetQuery">
            重置
          </el-button>
        </el-form-item>
      </el-form>
    </div>
    <el-divider class="el-divider--horizontal-margin" />
    <div style="margin-bottom: 10px;display: flex;align-items: center;">
      <label>当前路径：</label>
      <span>
        <el-link underline="underline" type="primary" @click="enter(null)">&nbsp;/&nbsp;</el-link>
        <span style="color: #ccc;">|</span>
      </span>
      <span v-for="(item,index) in dirs" :key="index">
        <el-link :underline="true" type="primary" @click="enter(item)">&nbsp;{{ item.fileName }}&nbsp;</el-link>
        <span style="color: #ccc;">|</span>
      </span>
      <span style="margin-left: 20px;"></span>
      <attachmentUpload v-model="files" :isShowTip="false" :oParentId="dirs.length > 0 ? dirs[dirs.length - 1].id : null" :oType="1" @uploadedSuccess="uploadedSuccessFn" />
      <!--
      <el-button type="primary" plain @click="handleUpload(dirs[dirs.length - 1])">
        <svg-icon icon-class="upload" />
        <span>上传文件到此目录</span>
      </el-button>
      -->
      <span style="margin-left: 20px;"></span>
      <el-button type="primary" plain @click="enter(dirs[dirs.length - 2])">
        <svg-icon icon-class="up" />
        <span>返回上级目录</span>
      </el-button>
      <span style="margin-left: 20px;"></span>
      <el-button type="success" plain @click="handleAddDirectory(dirs[dirs.length - 1]?.id)">
        <svg-icon icon-class="dir" />
        新建文件夹
      </el-button>
      <span style="margin-left: 20px;"></span>
      <el-button type="danger" plain @click="handleBatchDelete">
        <svg-icon icon-class="delete" />
        批量删除
      </el-button>
      <!--
      <el-button type="primary" plain @click="handleBatchDownload">
        <svg-icon icon-class="download" />
        打包下载
      </el-button>
      -->
    </div>
    <el-table v-loading="listLoading"
              :key="tableKey"
              :data="arrChangeTreeFn(list)"
              row-key="id"
              fit
              tooltip-effect="dark"
              @sort-change="handleSortChange"
              @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="39px" />
      <!--
      <el-table-column align="center" type="index" label="序号" width="60px" />
      <el-table-column v-if="isDebug" align="center" label="ID" prop="id" width="60px" show-overflow-tooltip />
      <el-table-column align="center" label="附件类型" prop="attachmentType" min-width="120px" show-overflow-tooltip>
        <template v-slot="{row}">
          <EnumTag :enum-list="getEnumList('AttachmentType')" :enum-key="row.attachmentType" />
        </template>
      </el-table-column>
      -->
      <el-table-column label="名称" prop="fileName" min-width="400px" sortable show-overflow-tooltip>
        <template v-slot="{row}">
          <div :class="isPointer(row)" @dblclick="enter(row)" title="双击进入该目录">
            <svg-icon :icon-class="getIconClassByFileName(row.fileName)" />
            <span v-if="row.attachmentType === '1'" style="font-weight: bold;">{{ row.fileName }}</span>
            <span v-if="row.attachmentType === '2'">{{ row.fileName }}</span>
          </div>
        </template>
      </el-table-column>
      <el-table-column align="center" label="类型" min-width="150px" sortable show-overflow-tooltip>
        <template v-slot="{row}">
          <span v-if="row.attachmentType === '1'">
            <EnumTag :enum-list="getEnumList('AttachmentType')" :enum-key="row.attachmentType" />
          </span>
          <span v-if="row.attachmentType === '2'">
            <DictTag :dict-list="getDictList('FileType')" :dict-key="row.fileType" />
          </span>
        </template>
      </el-table-column>
      <el-table-column align="center" label="大小" prop="fileSize" min-width="100px" sortable show-overflow-tooltip>
        <template v-slot="{row}">{{ bytesToSize(row.fileSize) }}</template>
      </el-table-column>
      <!--
      <el-table-column align="center" label="附件下载次数" prop="downloads" min-width="155px" show-overflow-tooltip />
      <el-table-column align="center" label="附件引用次数" prop="references" min-width="155px" show-overflow-tooltip />
      <el-table-column align="center" label="附件上传人用户ID" prop="uploader" min-width="230px" show-overflow-tooltip />
      <el-table-column align="center" label="附件上传人姓名" prop="uploaderName" min-width="180px" show-overflow-tooltip />
      -->
      <el-table-column align="center" label="适用模块" prop="module" min-width="100px" show-overflow-tooltip>
        <template v-slot="{row}">
          <EnumTag :enum-list="getEnumList('Module')" :enum-key="row.module" />
        </template>
      </el-table-column>
      <!--
      <el-table-column align="center" label="上级附件ID" prop="parentId" min-width="155px" show-overflow-tooltip />
      -->
      <el-table-column align="center" label="创建时间" width="180px" prop="createTime" sortable show-overflow-tooltip>
        <template v-slot="{row}"><DateTag :timestamp="row.createTime" /></template>
      </el-table-column>
      <el-table-column align="center" label="最后修改时间" width="180px" prop="updateTime" sortable show-overflow-tooltip>
        <template v-slot="{row}"><DateTag :timestamp="row.updateTime" /></template>
      </el-table-column>
      <el-table-column align="center" label="操作" width="200px" fixed="right">
        <template v-slot="{row}">
          <div class="" style="display: flex;align-items: center;">
            <el-button v-show="checkAuthByCode('')"
                       type="success"
                       link
                       title="查看"
                       @click="handleView(row)">
              <svg-icon icon-class="view" />
            </el-button>
            <el-button v-show="checkAuthByCode('')"
                       type="primary"
                       link
                       title="重命名"
                       @click="handleEdit(row)">
              <svg-icon icon-class="rename" />
            </el-button>
            <el-popconfirm confirm-button-text="确定"
                           cancel-button-text="取消"
                           :icon="WarningFilled"
                           icon-color="#626AEF"
                           title="您确定删除么？"
                           @confirm="handleDelete(row)"
                           v-if="checkAuthByCode('') && row.references === 0">
              <template #reference>
                <el-button type="danger"
                           link
                           title="删除">
                  <svg-icon icon-class="delete" />
                </el-button>
              </template>
            </el-popconfirm>
            <el-button v-show="checkAuthByCode('')"
                       type="primary"
                       link
                       title="新增子文件夹"
                       @click="handleAddDirectory(row.id)"
                       v-if="row.attachmentType === '1'">
              <svg-icon icon-class="add" />
            </el-button>
            <span v-show="checkAuthByCode('')" style="padding-top: 5px;padding-left: 10px;">
              <attachmentUpload v-if="row.attachmentType === '1'" :isShowTip="false" v-model="files" :oParentId="row.id" :oType="2" @uploadedSuccess="uploadedSuccessFn" />
            </span>
            <!--
            <el-button v-show="checkAuthByCode('')"
                       type="warning"
                       link
                       title="上传文件"
                       @click="handleUpload(row)"
                       v-if="row.attachmentType === '1'">
              <svg-icon icon-class="upload" />
            </el-button>
            -->
            <el-button v-show="checkAuthByCode('')"
                       type="info"
                       link
                       title="下载文件"
                       @click="handleDownload(row)"
                       v-if="row.attachmentType === '2'">
              <svg-icon icon-class="downloads" />
            </el-button>
            <el-button v-show="checkAuthByCode('')"
                       type="success"
                       link
                       title="预览文件"
                       @click="handlePreview(row)"
                       v-if="row.attachmentType === '2' && canPreview(row.fileName)">
              <svg-icon icon-class="preview" />
            </el-button>
          </div>
        </template>
      </el-table-column>
    </el-table>
    <pagination v-model:total="total" v-model:page="listQuery.pageNum" v-model:limit="listQuery.pageSize" @pagination="getList" />
    <el-dialog v-model="dialogVisible" :title="dialogTypeTitle" width="60%" top="2vh">
      <el-form class="my-form" ref="obj" :model="obj" :rules="rules" label-position="right" :disabled="dialogType === 'view'" label-width="auto">
        <el-form-item v-show="isDebug" label="ID">
          <text>{{ obj.id }}</text>
        </el-form-item>
        <el-form-item label="附件类型" prop="attachmentType" v-if="obj.attachmentType === '2'" v-show="isDebug">
          <el-radio-group v-model="obj.attachmentType" disabled>
            <el-radio-button v-for="(item,index) in getEnumList('AttachmentType')" :label="item.key" :key="index">{{item.value}}</el-radio-button>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="文件类型" prop="fileType" v-if="obj.attachmentType === '2'">
          <el-select v-model="obj.fileType" class="m-2" placeholder="请选择" disabled>
            <el-option key="" label="请选择" value="" />
            <el-option v-for="item in getDictList('FileType')" :key="item.key" :label="`${item.key} - ${item.value}`" :value="item.key" />
          </el-select>
        </el-form-item>
        <el-form-item label="名称" prop="fileName">
          <el-input v-model="obj.fileName" placeholder="请输入名称，最多输入200个字符" />
        </el-form-item>
        <el-form-item label="适用模块" prop="module">
          <el-radio-group v-model="obj.module">
            <el-radio-button label="" key="">全部</el-radio-button>
            <el-radio-button v-for="(item,index) in getEnumList('Module')" :label="item.key" :key="index">{{item.value}}</el-radio-button>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="上级文件夹" prop="parentId" v-if="isDebug">
          <el-cascader v-model="obj.parentId" :options="arrChangeTreeFn(directoryList)" :props="{label: 'fileName', value: 'id', checkStrictly: true}" :show-all-levels="false" clearable filterable />
        </el-form-item>
        <el-form-item label="附件大小" prop="fileSize" v-if="obj.attachmentType === '2'">
          <text>{{ bytesToSize(obj.fileSize) }}</text>
        </el-form-item>
        <el-form-item label="附件下载次数" prop="downloads" v-if="obj.attachmentType === '2'">
          <text>{{ obj.downloads }}</text>
        </el-form-item>
        <el-form-item label="附件引用次数" prop="references" v-if="obj.attachmentType === '2'">
          <text>{{ obj.references }}</text>
        </el-form-item>
        <el-form-item label="附件上传人" prop="uploader" v-if="obj.attachmentType === '2'">
          <User v-model="obj.uploader" keyName="id" keyShow="name" placeholder="用户" title="用户查询" />
        </el-form-item>
        <el-form-item label="创建时间" v-if="obj.attachmentType === '2'">
          <text>{{ obj.createTime ? obj.createTime : '自动生成' }}</text>
        </el-form-item>
        <el-form-item label="最后修改时间" v-if="obj.attachmentType === '2'">
          <text>{{ obj.updateTime ? obj.updateTime : '自动生成' }}</text>
        </el-form-item>
        <el-form-item v-show="isDebug" label="数据版本">
          <text>{{ obj.version }}</text>
        </el-form-item>
      </el-form>
      <div style="text-align:right;">
        <el-button type="info" icon="Close" @click="dialogVisible=false">关闭</el-button>
        <el-button type="primary" icon="Check" v-show="dialogType !== 'view'" @click="doConfirm('obj')">确定</el-button>
      </div>
    </el-dialog>
    <el-dialog v-model="isShowAttPreViewVisible" title="附件预览" width="70%" top="2vh">
      <attachmentPreview v-model:attachmentId="previewAttachmentId" />
      <div style="text-align:right;">
        <el-button type="danger" @click="isShowAttPreViewVisible=false">关闭</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import baseConfig from '@/mixins/baseConfig'
import {doGet, doPost, doPut, doDelete, doGetDownload} from '@/config/http'
import {
  svc,
  alertErrorMsg,
  customValidator,
  notifySuccess,
  arrChangeTreeFn,
  getListPageSize,
  bytesToSize,
  alertWarningMsg, isNullOrUndefined
} from '@/config/common'
import attachmentPreview from "@/views/components/base/attachmentPreview";
import SvgIcon from "@/components/SvgIcon/index.vue";
import useUserStore from "@/store/modules/user";
import attachmentUpload from "./components/attachmentUpload.vue"
import {getUserId} from "@/config/cookie";
import User from "@/views/components/base/selectUser.vue";
import initListStore from '@/store/modules/initList'

const emptyObj = {
  attachmentId: null, // 附件ID
  attachmentType: null, // 附件类型
  fileType: null, // 文件类型
  fileName: null, // 名称
  fileSize: null, // 文件大小(字节)
  downloads: null, // 附件下载次数
  references: null, // 附件引用次数
  uploader: getUserId(), // 附件上传人用户ID
  uploaderName: null, // 附件上传人姓名
  module: null, // 适用模块
  parentId: null, // 上级附件ID
  id: null,
  createBy: null,
  createTime: null,
  updateBy: null,
  updateTime: null,
  deleted: null,
  version: null,
}

export default {
  name: 'attachment_nocache',
  components: {User, SvgIcon, attachmentPreview, attachmentUpload},
  mixins: [baseConfig],
  data() {
    return {
      obj: Object.assign({}, emptyObj),
      routes: [],
      dialogVisible: false,
      dialogType: 'add',
      dialogTypeTitle: '新增',
      checkStrictly: false,
      defaultProps: {
        children: 'children',
        label: 'title'
      },
      tableKey: 0,
      list: null,
      total: 0,
      listLoading: false,
      listQuery: {
        pageNum: 1,
        pageSize: getListPageSize(),
        sortField: 'id',
        sortType: 'desc',
        attachmentId: null,
        attachmentType: null,
        fileType: null,
        fileName: null,
        fileSize: null,
        downloads: null,
        references: null,
        uploader: getUserId(),
        uploaderName: null,
        module: null,
        parentId: null,
        createTimeStart: null,
        createTimeEnd: null,
        updateTimeStart: null,
        updateTimeEnd: null,
      },
      selectionList: [],
      dialogFormVisible: false,
      dialogStatus: '',
      rules: {
        attachmentId: [{ required: false, validator: customValidator, min: 0, max: 20, label: '附件ID', trigger: ['blur', 'change'] }],
        attachmentType: [{ required: false, validator: customValidator, min: 0, max: 20, label: '附件类型', trigger: ['blur', 'change'] }],
        fileType: [{ required: false, validator: customValidator, min: 0, max: 20, label: '文件类型', trigger: ['blur', 'change'] }],
        fileName: [{ required: true, validator: customValidator, min: 0, max: 200, label: '名称', trigger: ['blur', 'change'] }],
        fileSize: [{ required: false, validator: customValidator, min: 0, max: 20, label: '文件大小(字节)', trigger: ['blur', 'change'] }],
        downloads: [{ required: false, validator: customValidator, min: 0, max: 9, label: '附件下载次数', trigger: ['blur', 'change'] }],
        references: [{ required: false, validator: customValidator, min: 0, max: 9, label: '附件引用次数', trigger: ['blur', 'change'] }],
        uploader: [{ required: false, validator: customValidator, min: 0, max: 20, label: '附件上传人用户ID', trigger: ['blur', 'change'] }],
        uploaderName: [{ required: false, validator: customValidator, min: 0, max: 20, label: '附件上传人姓名', trigger: ['blur', 'change'] }],
        module: [{ required: false, validator: customValidator, min: 0, max: 20, label: '适用模块', trigger: ['blur', 'change'] }],
        parentId: [{ required: false, validator: customValidator, min: 0, max: 20, label: '上级附件ID', trigger: ['blur', 'change'] }],
      },
      userList: initListStore().userList,
      organizationList: initListStore().organizationList,
      directoryList: [],
      dirs: [],
      previewId: null,
      previewName: null,
      isShowAttPreViewVisible: false,
      previewAttachmentId: '',
      files: []
    }
  },
  computed: {
    routesData() {
      return this.routes
    },
  },
  created() {
    this.getList()
    this.initList()
  },
  methods: {
    useUserStore,
    bytesToSize,
    arrChangeTreeFn,
    async initList() {
      // let p1 = doGet(svc, '/user/page', {pageSize: getListPageSize()}, false)
      // let p2 = doGet(svc, '/organization/page', {pageSize: getListPageSize()}, false)
      let p1 = doGet(svc, '/file/page', {attachmentType: "1", pageSize: getListPageSize()}, false)
      let resArray = await Promise.all([p1])
      // this.userList = resArray[0]['records']
      // this.organizationList = resArray[1]['records']
      this.directoryList = resArray[0]['records']
    },
    getList() {
      this.listLoading = true
      doGet(svc, '/customFile/findFileList', this.listQuery).then(res => {
        this.listLoading = false
        this.list = res
      }).catch(e => {
        console.error(e)
        this.listLoading = false
      })
    },
    enter(row) {
      if (isNullOrUndefined(row)) {
        this.listQuery.parentId = null
        this.dirs = []
        this.handleFilter()
        return
      }
      if (row.attachmentType !== '1') {
        return
      }
      this.listQuery.parentId = row.id
      let find = this.dirs.find(item => item.id === row.id)
      if (find) {
        while (this.dirs.length > 0 && this.dirs.at(-1).id !== row.id) {
          this.dirs.pop()
        }
        this.dirs.pop()
      }
      this.dirs.push(row)
      this.handleFilter()
    },
    isPointer(row) {
      return row.attachmentType === '1' ? 'pointer' : ''
    },
    getIconClassByFileName(name) {
      if (name.indexOf('.') <= 0) {
        return "dirs"
      }
      let suffix = name.split('.')[name.split('.').length - 1].toLowerCase()
      switch (suffix) {
        case "jpg":
        case "jpeg":
          return "jpg1"
        case "png":
          return "png1"
        case "pdf":
          return "pdf"
        case "xls":
        case "xlsx":
          return "excel1"
        case "doc":
        case "docx":
          return "word1"
        case "ppt":
        case "pptx":
          return "powerpoint1"
        case "mp3":
          return "mp3"
        case "mp4":
          return "mp4"
        case "avi":
          return "avi1"
        case "txt":
        case "text":
          return "txt"
        case "7z":
          return "7z"
        case "zip":
          return "zip"
        case "rar":
          return "rar"
        default:
          return "normal"
      }
    },
    handleResetQuery() {
      this.resetForm("listQuery")
    },
    handleFilter() {
      this.listQuery.pageNum = 1
      this.getList()
    },
    handleModifyStatus(row, status) {
      this.$message({
        message: '操作Success',
        type: 'success'
      })
      row.status = status
    },
    handleSelectionChange(data) {
      this.selectionList = data
    },
    handleSortChange(data) {
      const { prop, order } = data
      this.listQuery.sortField = prop
      this.listQuery.sortType = order === 'ascending' ? 'asc' : 'desc'
      this.handleFilter()
    },
    handleEdit(row) {
      this.dialogType = 'edit'
      this.dialogTypeTitle = '编辑'
      this.dialogVisible = true
      this.checkStrictly = true
      this.obj = Object.assign({}, row)
    },
    handleView(row) {
      this.dialogType = 'view'
      this.dialogTypeTitle = '详情'
      this.dialogVisible = true
      this.checkStrictly = false
      this.obj = Object.assign({}, row)
    },
    handleAddDirectory(parentId) {
      this.dialogType = 'add'
      this.dialogTypeTitle = '新增文件夹'
      this.dialogVisible = true
      this.checkStrictly = true
      this.obj = Object.assign({}, emptyObj)
      this.obj.attachmentType = '1'
      this.obj.module = ""
      console.debug('parentId',parentId)
      if (parentId)
        this.obj.parentId = parentId
    },
    handleAdd() {
      this.dialogType = 'add'
      this.dialogTypeTitle = '新增'
      this.dialogVisible = true
      this.checkStrictly = true
      this.obj = Object.assign({}, emptyObj)
    },
    handleDelete(row) {
      doDelete(svc, '/file/' + row.id, {}).then(() => {
        notifySuccess('操作成功')
        this.getList()
        this.dialogVisible = false
      })
    },
    uploadedSuccessFn(data, parentId) {
      let o = {
        attachmentId: data.id, // 附件ID
        attachmentType: '2', // 附件类型
        fileType: data.fileType, // 文件类型
        fileName: data.original, // 名称
        fileSize: data.size, // 文件大小(字节)
        downloads: 0, // 附件下载次数
        references: 0, // 附件引用次数
        uploader: getUserId(), // 附件上传人用户ID
        uploaderName: null, // 附件上传人姓名
        module: null, // 适用模块
        parentId: parentId, // 上级附件ID
      }
      doPost(svc, '/file/add', o).then(() => {
        notifySuccess('操作成功')
        this.getList()
      })
    },
    handleBatchDownload() {
      if (this.selectionList.length === 0) {
        alertWarningMsg('请选择要打包的文件/文件夹')
        return
      }
      let ids = []
      this.selectionList.map(item => ids.push(item.id))
      doGetDownload(svc, '/customFile/downloads', {ids: ids.join(',')}, true)
    },
    handleBatchDelete() {
      if (this.selectionList.length === 0) {
        alertWarningMsg('请选择要删除的文件/文件夹')
        return
      }
      this.$confirm('您确定删除选择的文件/文件夹么？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        let ids = []
        let err = ''
        this.selectionList.map(item => {
          if (item.references > 0) {
            err = '附件[' + item.fileName + ']已经被其他单据引用，不能删除。'
          }
          ids.push(item.id)
        })
        if (err !== '') {
          alertErrorMsg(err)
          return
        }
        doPost(svc, '/customFile/deletes', {ids: ids.join(',')}, true).then(() => {
          notifySuccess('操作成功')
          this.getList()
          this.dialogVisible = false
        })
      })
    },
    handleDownload(row) {
      doGetDownload(svc, '/customAttachment/download/' + row.attachmentId, {})
    },
    canPreview(filename) {
      let low = filename?.toLowerCase()
      return low.endsWith(".pdf") || low.endsWith(".docx") || low.endsWith(".xlsx") || low.endsWith(".xls") || low.endsWith(".png") || low.endsWith(".jpg") || low.endsWith(".jpeg")
    },
    handlePreview(row) {
      this.isShowAttPreViewVisible = true
      setTimeout(() => {
        this.previewAttachmentId = row.attachmentId
      },10)
    },
    async doConfirm(formName) {
      let v = await this.$refs[formName].validate().catch((err)=>{return err})
      if (v !== true) {
        alertErrorMsg('表单验证不通过，请检查数据。')
        return
      }
      if (this.obj.parentId instanceof Array) {
        this.obj.parentId = this.obj.parentId[this.obj.parentId.length - 1]
      }
      switch (this.dialogType) {
        case "add":
          doPost(svc, '/file/add', this.obj).then(() => {
            notifySuccess('新增成功')
            this.getList()
            this.dialogVisible = false
          })
          break;
        case "edit":
          doPut(svc, '/file/modify', this.obj).then(() => {
            notifySuccess('修改成功')
            this.getList()
            this.dialogVisible = false
          })
          break;
      }
    }
  }
}
</script>
